package com.duck.duckchatbackend.controller;

import com.duck.duckchatbackend.annotation.GlobalInterceptor;
import com.duck.duckchatbackend.entity.constans.Constants;
import com.duck.duckchatbackend.entity.dto.MessageSendDto;
import com.duck.duckchatbackend.entity.dto.SysSettingDto;
import com.duck.duckchatbackend.entity.dto.TokenUserInfoDto;
import com.duck.duckchatbackend.entity.vo.ResponseVO;

import com.duck.duckchatbackend.entity.vo.UserInfoVO;
import com.duck.duckchatbackend.exception.BusinessException;
import com.duck.duckchatbackend.redis.RedisComponent;

import com.duck.duckchatbackend.redis.RedisUtils;
import com.duck.duckchatbackend.service.UserInfoService;
import com.duck.duckchatbackend.utils.CopyTools;
import com.duck.duckchatbackend.websocket.MessageHandler;
import com.wf.captcha.ArithmeticCaptcha;

import org.apache.logging.log4j.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/*
*
* */
@RestController("accountController")
@RequestMapping("/account")
@Validated
public class AccountController extends ABaseController {
    private static final Logger logger = LoggerFactory.getLogger(AccountController.class);

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private RedisComponent redisComponent;

    @Resource
    private MessageHandler messageHandler;


    @RequestMapping("/checkCode")
    public ResponseVO checkCode()
    {
        // 创建一个算术验证码对象，指定验证码的宽度和高度
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(100, 42);
        // 生成验证码字符串
        String code = captcha.text(); //验证结果
        // 生成一个唯一的验证码键
        String checkCodeKey = UUID.randomUUID().toString();
        // 将验证码存储到Redis中，并设置过期时间
        redisUtils.setex(Constants.REDIS_KEY_CHECK_CODE+checkCodeKey,code,Constants.REDIS_KEY_EXPIRES_ONE_MIN * 10);
        // 记录日志，输出验证码
        logger.info("验证码是{}",code);
        // 将验证码转换为Base64编码的字符串
        String checkCodeBase64 = captcha.toBase64();
        // 创建一个结果映射，用于存储验证码和验证码键
        Map<String,String> result = new HashMap<>();
        result.put("checkCode",checkCodeBase64);
        result.put("checkCodeKey",checkCodeKey);
        // 返回包含验证码信息的成功响应对象
        return getSuccessResponseVO(result);
    }

    /**
     * 处理用户注册请求
     *
     * @param checkCodeKey 验证码键，用于从Redis中获取验证码
     * @param email 用户邮箱，也是登录账号
     * @param password 用户密码
     * @param nickName 用户昵称
     * @param checkCode 用户输入的验证码
     * @return 返回注册结果的响应对象
     *
     * 此方法负责验证用户提交的验证码是否正确，如果正确则调用用户信息服务进行注册
     * 验证码在验证完成后会被删除，以确保每个验证码只能使用一次
     */
    @RequestMapping("/register")
    public ResponseVO register(@NotEmpty String checkCodeKey,
                               @NotEmpty @Email String email,
                               @NotEmpty @Pattern(regexp = Constants.REGEX_PASSWORD)String password,
                               @NotEmpty String nickName,
                               @NotEmpty String checkCode)
    {
        // 尝试执行注册逻辑
        try{
            // 检查用户提交的验证码与Redis中存储的验证码是否匹配
            if(!checkCode.equals(redisUtils.get(Constants.REDIS_KEY_CHECK_CODE+checkCodeKey))){
                // 如果验证码不匹配，则抛出业务异常
                throw  new BusinessException("图片验证码不正确");
            }
            // 调用用户信息服务进行注册
            userInfoService.register(email,nickName,password);
            // 返回成功的响应对象
            return getSuccessResponseVO(null);
        } finally {
            // 无论注册是否成功，都删除验证码，以保证验证码只能使用一次
            redisUtils.delete(Constants.REDIS_KEY_CHECK_CODE+checkCodeKey);
        }
    }

    /**
     * 处理用户登录请求
     *
     * @param checkCodeKey 验证码键，用于从Redis中获取对应的验证码值
     * @param email 用户邮箱，作为登录凭证之一
     * @param password 用户密码，作为登录凭证之一
     * @param checkCode 用户输入的验证码值
     * @return 返回登录结果，封装在ResponseVO对象中
     *
     * 此方法负责验证用户提供的登录信息，包括验证码的校验和用户凭据的验证
     * 验证码的校验是通过将用户输入的验证码与存储在Redis中的验证码值进行比较来完成的
     * 如果验证码不匹配，则抛出业务异常，提示验证码不正确
     * 如果验证码匹配，则调用 userInfoService 的 login 方法进行用户登录逻辑处理
     * 登录成功后，返回一个表示成功响应的对象，并清除Redis中的验证码值
     */
    @RequestMapping("/login")
    public ResponseVO login(@NotEmpty String checkCodeKey,
                            @NotEmpty @Email String email,
                            @NotEmpty String password,
                            @NotEmpty String checkCode
                            ) {
        try {
            // 验证码校验，如果不符合则抛出异常
            if(!checkCode.equals(redisUtils.get(Constants.REDIS_KEY_CHECK_CODE+checkCodeKey))){
                throw  new BusinessException("图片验证码不正确");
            }
            // 登录逻辑处理，成功后返回用户信息
            UserInfoVO userInfoVO = userInfoService.login(email,password);
            return getSuccessResponseVO(userInfoVO);
        } finally {
            // 无论登录是否成功，都清除Redis中的验证码值
            redisUtils.delete(Constants.REDIS_KEY_CHECK_CODE+checkCodeKey);
        }
    }

    @RequestMapping(value = "/test")
    public ResponseVO test() {
        MessageSendDto sendDto = new MessageSendDto();
        sendDto.setMessageContent("hahahahaha"+System.currentTimeMillis());
        messageHandler.sendMessage(sendDto);
        return getSuccessResponseVO(null);
    }
}
